package com.docker.common.common.ui.location;

import android.arch.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.TextView;

import com.alibaba.android.arouter.facade.annotation.Route;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.model.inner.GeoPoint;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
import com.baidu.mapapi.search.poi.OnGetPoiSearchResultListener;
import com.baidu.mapapi.search.poi.PoiCitySearchOption;
import com.baidu.mapapi.search.poi.PoiDetailResult;
import com.baidu.mapapi.search.poi.PoiDetailSearchResult;
import com.baidu.mapapi.search.poi.PoiIndoorResult;
import com.baidu.mapapi.search.poi.PoiNearbySearchOption;
import com.baidu.mapapi.search.poi.PoiResult;
import com.baidu.mapapi.search.poi.PoiSearch;
import com.docker.common.R;
import com.docker.common.common.adapter.NitAbsSampleAdapter;
import com.docker.common.common.router.AppRouter;
import com.docker.common.common.ui.base.NitCommonActivity;
import com.docker.common.common.vm.NitEmptyViewModel;
import com.docker.common.common.vo.BaiduMapAddressVo;
import com.docker.common.databinding.CommonActivityMapLocationBinding;
import com.docker.core.util.adapter.SimpleCommonRecyclerAdapter;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import me.tatarka.bindingcollectionadapter2.BR;

@Route(path = AppRouter.COMMON_LOCATION_ACTIVITY)
public class MapLocationActivity extends NitCommonActivity<NitEmptyViewModel, CommonActivityMapLocationBinding> implements OnGetGeoCoderResultListener {
    private LocationClient locationClient;
    private MapView mMapView;
    private BaiduMap mBaiduMap;
    LatLng latLng;
    GeoCoder geoCoder;
    MylocationListener myListener;

    private NitAbsSampleAdapter nitAbsSampleAdapter;
    private NitAbsSampleAdapter nitSearchAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initBaiduMapView();
        mBinding.linBack.setOnClickListener(v -> finish());
        nitAbsSampleAdapter = new NitAbsSampleAdapter(R.layout.common_item_loc_address, BR.item) {
            @Override
            public void onRealviewBind(ViewHolder holder, int position) {

            }
        };
        nitSearchAdapter = new NitAbsSampleAdapter(R.layout.common_item_loc_address, BR.item) {
            @Override
            public void onRealviewBind(ViewHolder holder, int position) {

            }
        };
        mBinding.recycleSearch.setAdapter(nitSearchAdapter);
        mBinding.recycle.setAdapter(nitAbsSampleAdapter);
        mBinding.recycle.setLayoutManager(new LinearLayoutManager(this));
        mBinding.recycleSearch.setLayoutManager(new LinearLayoutManager(this));
        nitAbsSampleAdapter.setOnItemClickListener((view, position) -> {
            Intent data = new Intent();
            BaiduMapAddressVo baiduMapAddressVo = (BaiduMapAddressVo) nitAbsSampleAdapter.getItem(position);
            baiduMapAddressVo.lat = String.valueOf(baiduMapAddressVo.latLng.latitude);
            baiduMapAddressVo.lng = String.valueOf(baiduMapAddressVo.latLng.longitude);
            data.putExtra("addressvo", baiduMapAddressVo);
            setResult(RESULT_OK, data);
            finish();
        });

        nitSearchAdapter.setOnItemClickListener((view, position) -> {
            mBinding.recycleSearch.setVisibility(View.GONE);
            mBinding.edSerch.setText("");
            address = ((BaiduMapAddressVo) nitSearchAdapter.getItem(position)).Name;
            latLng = getGeoPointBystr(((BaiduMapAddressVo) nitSearchAdapter.getItem(position)).Name);
            MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(latLng);
            new Handler().postDelayed(() -> mBaiduMap.animateMapStatus(u), 100);
            nearbyPoiSearch(latLng);

        });

        mBinding.tvSure.setOnClickListener(v -> {
            PoiSearch(mBinding.edSerch.getText().toString());
        });

        mBinding.edSerch.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                if (TextUtils.isEmpty(mBinding.edSerch.getText().toString())) {
                    mBinding.tvSure.setVisibility(View.GONE);
                    mBinding.recycleSearch.setVisibility(View.GONE);
                } else {
                    mBinding.tvSure.setVisibility(View.VISIBLE);
                }
            }
        });

        mBinding.edSerch.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
        mBinding.edSerch.setOnEditorActionListener((v, actionId, event) -> {
            if (actionId == EditorInfo.IME_ACTION_SEARCH || (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {
                PoiSearch(mBinding.edSerch.getText().toString());
                return true;
            }
            return false;
        });
    }

    public LatLng getGeoPointBystr(String str) {
        LatLng latLng = null;
        if (str != null) {
            Geocoder gc = new Geocoder(this, Locale.CHINA);
            List<Address> addressList = null;
            try {
                addressList = gc.getFromLocationName(str, 1);
                if (!addressList.isEmpty()) {
                    Address address_temp = addressList.get(0);
                    //计算经纬度
                    double Latitude = address_temp.getLatitude();
                    double Longitude = address_temp.getLongitude();
                    System.out.println("经度:" + Latitude);
                    System.out.println("纬度:" + Longitude);
                    latLng = new LatLng(Latitude, Longitude);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return latLng;
    }


    public void PoiSearch(String name) {
        //创建poi检索实例
        PoiSearch poiSearch = PoiSearch.newInstance();
        //创建poi监听者
        OnGetPoiSearchResultListener poiListener = new OnGetPoiSearchResultListener() {
            @Override
            public void onGetPoiResult(PoiResult result) {
                //获取POI检索结果
                Log.d("TAG", "onGetPoiResult: ====================" + result.toString());

                if (result.getAllPoi() != null) {
                    mBinding.recycleSearch.setVisibility(View.VISIBLE);
                    ArrayList<BaiduMapAddressVo> addressVos = new ArrayList<>();
                    for (int i = 0; i < result.getAllPoi().size(); i++) {
                        BaiduMapAddressVo baiduMapAddressVo = new BaiduMapAddressVo();
                        baiduMapAddressVo.Name = result.getAllPoi().get(i).name;
                        if(TextUtils.isEmpty(result.getAllPoi().get(i).getAddress())){
                            baiduMapAddressVo.detail = result.getAllPoi().get(i).name;
                        }else {
                            baiduMapAddressVo.detail = result.getAllPoi().get(i).getAddress();
                        }
                        baiduMapAddressVo.latLng = result.getAllPoi().get(i).location;
                        baiduMapAddressVo.citycode = String.valueOf(citycode);
                        addressVos.add(baiduMapAddressVo);
                    }
                    nitSearchAdapter.clear();
                    nitSearchAdapter.add(addressVos);
                }

            }

            @Override
            public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {

            }

            @Override
            public void onGetPoiDetailResult(PoiDetailSearchResult poiDetailSearchResult) {

            }

            @Override
            public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {

            }
        };
        //设置poi监听者该方法要先于检索方法searchNearby(PoiNearbySearchOption)前调用，否则会在某些场景出现拿不到回调结果的情况
        poiSearch.setOnGetPoiSearchResultListener(poiListener);
        //设置请求参数

        PoiCitySearchOption poiCitySearchOption = new PoiCitySearchOption();
        poiCitySearchOption.city(name).pageCapacity(50).keyword(name);
        //发起请求
        poiSearch.searchInCity(poiCitySearchOption);
        //释放检索对象
        poiSearch.destroy();
    }


    @Override
    public void initView() {
        mToolbar.hide();

        findViewById(R.id.btn_location).setOnClickListener(v -> {
            if (!locationClient.isStarted()) {
                locationClient.start();
            }
            locationClient.requestLocation();
        });

    }

    @Override
    public void initObserver() {

    }

    @Override
    public void initRouter() {

    }


    public class MylocationListener implements BDLocationListener {

        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
            if (bdLocation == null || mMapView == null) {
                return;
            }
            latLng = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
            MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(latLng);
            mBaiduMap.animateMapStatus(u);
            geoCoder.reverseGeoCode(new ReverseGeoCodeOption()
                    .location(latLng));
            locationClient.stop();

        }
    }


    private void initBaiduMapView() {

        geoCoder = GeoCoder.newInstance();
        locationClient = new LocationClient(this.getApplicationContext());
        LocationClientOption locationClientOption = new LocationClientOption();
        locationClientOption.setOpenGps(true);
        locationClientOption.disableCache(true);
        locationClientOption.setCoorType("bd09ll");
        locationClientOption.setAddrType("all");
        locationClientOption.setPriority(LocationClientOption.NetWorkFirst);
        locationClient.setLocOption(locationClientOption);
        myListener = new MylocationListener();
        locationClient.registerLocationListener(myListener);
        locationClient.start();
        locationClient.requestLocation();

        mMapView = findViewById(R.id.map_view);
        mBaiduMap = mMapView.getMap();
        mBaiduMap.setMapStatus(MapStatusUpdateFactory.zoomTo(18));
        // 开启定位图层
        mBaiduMap.setMyLocationEnabled(true);
        // 初始化搜索模块，注册事件监听
        geoCoder = GeoCoder.newInstance();
        geoCoder.setOnGetGeoCodeResultListener(this);
        mBaiduMap.setOnMapStatusChangeListener(new BaiduMap.OnMapStatusChangeListener() {
            /**
             * 手势操作地图，设置地图状态等操作导致地图状态开始改变。
             * @param status 地图状态改变开始时的地图状态
             */
            public void onMapStatusChangeStart(MapStatus status) {
                mBaiduMap.clear();
            }

            @Override
            public void onMapStatusChangeStart(MapStatus mapStatus, int i) {
                mBaiduMap.clear();
            }

            /**
             * 地图状态变化中
             * @param status 当前地图状态
             */
            public void onMapStatusChange(MapStatus status) {
            }

            /**
             * 地图状态改变结束
             * @param status 地图状态改变结束后的地图状态
             */
            public void onMapStatusChangeFinish(MapStatus status) {
                LatLng ll = status.target;
                geoCoder.reverseGeoCode(new ReverseGeoCodeOption().location(ll));


            }
        });


    }


    @Override
    public void onPause() {
        if (mMapView != null) {
            mMapView.onPause();
        }
        super.onPause();
    }

    @Override
    public void onResume() {
        if (mMapView != null) {
            mMapView.onResume();
        }
        super.onResume();
    }

    @Override
    public void finish() {
        if (locationClient != null && locationClient.isStarted()) {
            if (myListener != null) {
                locationClient.unRegisterLocationListener(myListener);
            }
            locationClient.stop();
            locationClient = null;
            mMapView = null;
        }
        super.finish();
    }


    @Override
    public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {
        if (geoCodeResult == null
                || geoCodeResult.error != SearchResult.ERRORNO.NO_ERROR) {
            // 没有检测到结果
        }

//        mBinding.tvAddress.setVisibility(View.VISIBLE);
//        mBinding.tvAddress.setText(geoCodeResult.ge());
        // todo
        final MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(geoCodeResult.getLocation());
        new Handler().postDelayed(() -> mBaiduMap.animateMapStatus(u), 100);
    }

    String address;
    int citycode;

    @Override
    public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
        if (locationClient != null) {
            latLng = result.getLocation();
            if (result == null
                    || result.error != SearchResult.ERRORNO.NO_ERROR) {
            }

            Log.d("TAG", "onGetReverseGeoCodeResult: =====================" + address);
            if (result.getAddressDetail() != null) {
                if ((result.getAddressDetail().street + result.getAddressDetail().streetNumber).equals(address)) {
                    return;
                }
                address = result.getAddressDetail().street + result.getAddressDetail().streetNumber;
                citycode = result.getCityCode();
            }
            final MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(result.getLocation());
            new Handler().postDelayed(() -> mBaiduMap.animateMapStatus(u), 100);
            nearbyPoiSearch(latLng);
        }
    }

    public void nearbyPoiSearch(LatLng latLng) {

        if (latLng == null) {
            return;
        }
        //创建poi检索实例
        PoiSearch poiSearch = PoiSearch.newInstance();
        //创建poi监听者
        OnGetPoiSearchResultListener poiListener = new OnGetPoiSearchResultListener() {
            @Override
            public void onGetPoiResult(PoiResult result) {
                //获取POI检索结果
                Log.d("TAG", "onGetPoiResult: ====================" + result.toString());

                if (result.getAllPoi() != null) {
                    ArrayList<BaiduMapAddressVo> addressVos = new ArrayList<>();
                    for (int i = 0; i < result.getAllPoi().size(); i++) {
                        BaiduMapAddressVo baiduMapAddressVo = new BaiduMapAddressVo();
                        baiduMapAddressVo.detail = result.getAllPoi().get(i).getAddress();
                        baiduMapAddressVo.Name = result.getAllPoi().get(i).city;
                        baiduMapAddressVo.latLng = result.getAllPoi().get(i).location;
                        baiduMapAddressVo.citycode = String.valueOf(citycode);
                        addressVos.add(baiduMapAddressVo);
                    }
                    nitAbsSampleAdapter.clear();
                    nitAbsSampleAdapter.add(addressVos);
                }


            }

            @Override
            public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {

            }

            @Override
            public void onGetPoiDetailResult(PoiDetailSearchResult poiDetailSearchResult) {

            }

            @Override
            public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {

            }
        };
        //设置poi监听者该方法要先于检索方法searchNearby(PoiNearbySearchOption)前调用，否则会在某些场景出现拿不到回调结果的情况
        poiSearch.setOnGetPoiSearchResultListener(poiListener);
        //设置请求参数
        PoiNearbySearchOption nearbySearchOption = new PoiNearbySearchOption()
                .keyword("餐厅")//检索关键字
                .location(latLng)//检索位置
                .pageNum(0)//分页编号，默认是0页
                .pageCapacity(20)//设置每页容量，默认10条
                .radius(1000);//附近检索半径
        //发起请求
        poiSearch.searchNearby(nearbySearchOption);
        //释放检索对象
        poiSearch.destroy();
    }


    @Override
    protected int getLayoutId() {
        return R.layout.common_activity_map_location;
    }

    @Override
    public NitEmptyViewModel getmViewModel() {
        return ViewModelProviders.of(this).get(NitEmptyViewModel.class);
    }


}
